package labbd_._projetofinal;

import java.awt.Image;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleTypes;
import oracle.sql.BLOB;



/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author bimaoe
 */
public class Produto {

	private int idProduto;
	private String tipo;
	private String empresa;
	private double valor;
	private String descricao;
	private Blob foto;

	public Produto(int idProduto, String tipo, double valor, String descricao, String empresa, Blob foto) {
		this.idProduto = idProduto;
		this.tipo = tipo;
		this.empresa = empresa;
		this.valor = valor;
		this.descricao = descricao;
		this.foto = foto;
	}

	public String getEmpresa() {
		return empresa;
	}

	public String getDescricao() {
		return descricao;
	}

	public Image getFoto() {
		return getImage(foto);
	}

        public Blob getFotoBlob(){
            return foto;
        }

	public int getIdProduto() {
		return idProduto;
	}

	public String getTipo() {
		return tipo;
	}

	public double getValor() {
		return valor;
	}
	public static void novoProduto (OracleConnection in_conn, double in_valor,
		String in_descricao, String in_tipo, BigDecimal in_cnpjempresa,
		String in_caminho) throws SQLException, FileNotFoundException, IOException, Exception {
            
		String query = "begin ? := pkg_produto.func_novoProduto (?,?,?,?,?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) in_conn.prepareCall(query);
		Ocallstmt.registerOutParameter(1, java.sql.Types.INTEGER);
		Ocallstmt.registerOutParameter(2, java.sql.Types.BLOB);
		Ocallstmt.setDouble(3, in_valor);
		Ocallstmt.setString(4, in_descricao);
		Ocallstmt.setString(5, in_tipo);
		Ocallstmt.setBigDecimal(6, in_cnpjempresa);
		try {
			Ocallstmt.execute();
			if (in_caminho.equals("")) { //Passou um caminho pra foto
				in_caminho = "./images/noimage.jpg";
			}
			BLOB fotoBlob = (BLOB) Ocallstmt.getObject(2);
			alteraFoto(fotoBlob , in_caminho);
			Ocallstmt.close();
			in_conn.commit();
			System.err.println ("Produto Cadastrado");
		} catch (SQLException ex) {
			System.err.println ("Exception: "+ex.getMessage() + ex.getErrorCode());
			ex.printStackTrace();
			in_conn.rollback();
			throw ex;
		} finally {
			in_conn.setAutoCommit(true);
		}
	}
	public static ArrayList<Produto> getProdutosValidos (OracleConnection in_conn)
		throws SQLException {
		in_conn.commit();
		in_conn.setAutoCommit(false);
		String query = "begin pkg_produto.proc_getProdutosValidos (?); end;";
		OracleCallableStatement Ocallstmt = (OracleCallableStatement) in_conn.prepareCall(query);
		Ocallstmt.registerOutParameter(1, OracleTypes.CURSOR);

		ArrayList<Produto> ret = new ArrayList<Produto>();
		System.err.println("Pegando produtos validos");
		try {
                    Ocallstmt.execute();
                    ResultSet rs = (ResultSet) Ocallstmt.getObject(1);
                    System.out.println ("Produtos de hoje:");

                    while (rs.next()) {
                        System.err.println ("ID do produto: "+rs.getInt("IDPRODUTO")+
                                        " Tipo: "+rs.getString("TIPO")+
                                        " Valor original: "+rs.getDouble("VALOR")+
                                        " Empresa: "+rs.getString("EMPRESA"));
                        System.err.println ("\tDescricao: "+rs.getString ("DESCRICAO"));
                        System.err.println("Adicionando no array");
                        if(!ret.add(new Produto( rs.getInt("IDPRODUTO"), rs.getString("TIPO"),
                                        rs.getDouble("VALOR"), rs.getString ("DESCRICAO"),
                                        rs.getString ("EMPRESA"), rs.getBlob("FOTO")) ))
                                System.err.println("nao foi possivel adicionar");
                    }
                    rs.close();
		} catch (SQLException ex) {
				System.err.println ("Exception:"+ex.getMessage() + ex.getErrorCode());
		}
		if(ret.isEmpty()) System.err.println("Não há ofertas antes do retorno");
		return ret;
	}
	
	public static Image getImage(Blob foto){
		Image image = null;
		try {
			InputStream is = foto.getBinaryStream();
			image = ImageIO.read(is);

		} catch (IOException ex) {
			System.err.println ("Exception:"+ex.getMessage());
		} catch (SQLException ex) {
			System.err.println ("Exception:"+ex.getMessage() + ex.getErrorCode());
		}

		return image;
	}
	public static void alteraFoto (BLOB foto, String caminho) throws SQLException,
		FileNotFoundException, IOException, Exception {

		try {
			byte[] buffer = new byte[foto.getBufferSize()];
			int read;
			OutputStream os = foto.getBinaryOutputStream();
			FileInputStream fis = new FileInputStream(caminho);

			while((read = fis.read(buffer)) != -1){
					os.write(buffer, 0, read);
					System.err.println("Lendo buffer");
			}

			os.close();
			fis.close();
		} catch (SQLException ex) {
			ex.printStackTrace();
			throw ex;
		} catch (FileNotFoundException ex){
			System.err.println("Exception" + ex.getCause() + ex.getMessage());
		}

	}

        public void alteraFotoBlob(OracleConnection in_conn, String novaFoto) throws SQLException{
            String query = "begin ? := pkg_produto.func_getFoto(?); end;";

            in_conn.setAutoCommit(false);
            OracleCallableStatement OcallStmt = (OracleCallableStatement) in_conn.prepareCall(query);

            OcallStmt.registerOutParameter(1, java.sql.Types.BLOB);
            OcallStmt.setInt(2, this.idProduto);

            try {
                OcallStmt.execute();
                foto = (Blob) OcallStmt.getObject(1);
                System.err.println("Alterando a foto");
                alteraFoto((BLOB) this.foto, novaFoto);
                System.err.println("Foto alterada com sucesso");

                in_conn.commit();
            } catch (FileNotFoundException ex) {
                in_conn.rollback();
                Logger.getLogger(Produto.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(Produto.class.getName()).log(Level.SEVERE, null, ex);
                in_conn.rollback();
            } catch (Exception ex) {
                Logger.getLogger(Produto.class.getName()).log(Level.SEVERE, null, ex);
                in_conn.rollback();
            }
            finally{

                in_conn.setAutoCommit(true);
            }

        }
}
